package org.example.practiceexamples.service;

import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.example.practiceexamples.dox.Appointment;
import org.example.practiceexamples.dox.Course;
import org.example.practiceexamples.dox.Lab;
import org.example.practiceexamples.dox.User;
import org.example.practiceexamples.dto.UserAppointment;
import org.example.practiceexamples.dto.UserCourse;
import org.example.practiceexamples.dto.UserLab;
import org.example.practiceexamples.exception.Code;
import org.example.practiceexamples.exception.XException;
import org.example.practiceexamples.repository.AppointmentRepository;
import org.example.practiceexamples.repository.CourseRepository;
import org.example.practiceexamples.repository.UserRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.example.practiceexamples.tools.*;

import java.util.List;

@Slf4j
@Service
@AllArgsConstructor
public class TeacherService {
    private final UserRepository userRepository;
    private final AppointmentRepository appointmentRepository;
    private final CourseRepository courseRepository;

    @Transactional
    public void saveAppointment(Appointment appointment){
        appointmentRepository.save(appointment);
    }

    @Transactional
    public void saveCourse(Course course){
        courseRepository.save(course);
    }


    @Transactional
    public Appointment findAppointmentById(String id){
        return appointmentRepository.findById(id).orElse(null);
    }

    @Transactional
    public Course findCourseById(String cid){
        return courseRepository.findCourseById(cid);
    }

    @Transactional
    public void updatePassword(String uid,String account, String password){
        if(!userRepository.findUserByUid(uid).getAccount().equals(account)){
            throw XException.builder().code(Code.FORBIDDEN).message(Code.FORBIDDEN.getMessage()).build();
        }
        userRepository.updatePasswordByAccount(account, password);
    }

    @Transactional
    public void updatePasswordById(String uid, String password){
        userRepository.updatePasswordById(uid, password);
    }

    @Transactional
    public List<Course> findCoursesByAccount(String account){
        UserCourse userCourse= userRepository.findUserCourses(account);
        return userCourse.getCourses();
    }

    @Transactional
    public List<Course> findCoursesByUid(String uid){
        log.info(uid);
        UserCourse userCourse= userRepository.findUserCourse(uid);
        return userCourse.getCourses();
    }

    @Transactional
    public List<Lab> findLabsByAccount(String account){
        UserLab userLab = userRepository.findUserLabByAccount(account);
        return userLab.getLabs();
    }

    @Transactional
    public List<Lab> findLabsByUid(String uid){
        UserLab userLab = userRepository.findUserLabByUid(uid);
        return userLab.getLabs();
    }

    @Transactional
    public List<Appointment> findAllAppointments(){
        return appointmentRepository.findAllAppointments();
    }

    @Transactional
    public User findUserbyId(String uid){
        return userRepository.findUserByUid(uid);
    }
//    @Transactional
//    public List<Appointment> findAllAppointments(String account){
//        UserAppointment userAppointment = userRepository.findUserAppointmentByAccount(account);
//        return userAppointment.getAppointments();
//    }

    @Transactional
    public List<Appointment> findAllAppointmentsByUid(String uid){
        log.info(uid);
        UserAppointment userAppointment = userRepository.findUserAppointmentByUid(uid);
        return userAppointment.getAppointments();
    }

    @Transactional
    public String findPasswordByAccount(String account){
        return userRepository.findPasswordByAccount(account);
    }

    @Transactional
    public User findUserByAccount(String account){
        return userRepository.findUserByAccount(account);
    }


    @Transactional
    public void updateDescription(String uid, String description){
        userRepository.updateDescriptionById(uid,description);
    }

    @Transactional
    public void updatePhone(String uid,String account, String phone){
        if(!userRepository.findUserByUid(uid).getAccount().equals(account)){
            throw XException.builder().code(Code.FORBIDDEN).message(Code.FORBIDDEN.getMessage()).build();
        }
        userRepository.updatePhoneByAccount(account, phone);
    }

    @Transactional
    public void updatePhoneById(String uid, String phone){
        userRepository.updatePhoneById(uid, phone);
    }

    @Transactional
    public void updateProfession(String uid,String account, String profession){
        if(!userRepository.findUserByUid(uid).getAccount().equals(account)){
            throw XException.builder().code(Code.FORBIDDEN).message(Code.FORBIDDEN.getMessage()).build();
        }
        userRepository.updateProfessionByAccount(account, profession);
    }

    @Transactional
    public void updateProfessionById(String uid, String profession){
        userRepository.updateProfessionById(uid, profession);
    }


    @Transactional
    public void deleteAppointment(String uid,String account, String labName, int week, int day, int section){
        if(!userRepository.findUserByUid(uid).getAccount().equals(account)){
            throw XException.builder().code(Code.FORBIDDEN).message(Code.FORBIDDEN.getMessage()).build();
        }
        appointmentRepository.deleteAppointmentByLName(labName, week, day, section);
    }

    @Transactional
    public void deleteAppointmentById(String uid,String aid){
        Appointment a = appointmentRepository.findAppointmentById(aid);
        String teacherId = JsonTemp.toObject(a.getTeacher()).getId();
        if(uid!=teacherId){
            throw XException.builder().code(Code.FORBIDDEN).message(Code.FORBIDDEN.getMessage()).build();
        }
        appointmentRepository.deleteAppointmentById(aid);
    }

    @Transactional
    public void deleteCourseById(String uid,String cid){
        Course c = courseRepository.findCourseById(cid);
        if(uid!=c.getTeacherId()){
            throw XException.builder().code(Code.FORBIDDEN).message(Code.FORBIDDEN.getMessage()).build();
        }
        courseRepository.deleteById(cid);
    }

}
